using Rogan.Utility;
using Rogan.Utility.Common;
using Rogan.Utility.Extensions;
using System;
using System.Data;
using System.Data.Common;
using System.Data.OleDb;
using System.Text.RegularExpressions;
namespace Rogan.Data.MsAccess
{
	public class MsAccessProvider : DbProvider
	{
		public override string RowAutoID
		{
			get
			{
				return string.Empty;
			}
		}
		public override bool SupportBatch
		{
			get
			{
				return false;
			}
		}
		public MsAccessProvider(string connectionString) : base(connectionString, OleDbFactory.Instance, '[', ']', '@')
		{
		}
		public override void PrepareCommand(DbCommand cmd)
		{
			base.PrepareCommand(cmd);
			foreach (DbParameter dbParameter in cmd.Parameters)
			{
				if (dbParameter.Direction != ParameterDirection.Output && dbParameter.Direction != ParameterDirection.ReturnValue)
				{
					OleDbParameter oleDbParameter = (OleDbParameter)dbParameter;
					DbType dbType = oleDbParameter.DbType;
					object value = dbParameter.Value;
					if (value == DBNull.Value || value == null)
					{
						dbParameter.Value = DBNull.Value;
					}
					else
					{
						Type type = value.GetType();
						if (dbType != DbType.Guid && type == typeof(Guid))
						{
							oleDbParameter.OleDbType = OleDbType.Char;
							oleDbParameter.Size = 36;
						}
						else
						{
							if ((dbType == DbType.Time || dbType == DbType.DateTime) && type == typeof(TimeSpan))
							{
								oleDbParameter.OleDbType = OleDbType.Double;
								oleDbParameter.Value = ((TimeSpan)value).TotalDays;
							}
							else
							{
								DbType dbType2 = dbType;
								switch (dbType2)
								{
								case DbType.AnsiString:
									if (value.ToString().Length > 4000)
									{
										oleDbParameter.OleDbType = OleDbType.LongVarChar;
									}
									break;
								case DbType.Binary:
									if (((byte[])value).Length > 2000)
									{
										oleDbParameter.OleDbType = OleDbType.LongVarBinary;
									}
									break;
								default:
									if (dbType2 != DbType.DateTime)
									{
										switch (dbType2)
										{
										case DbType.Object:
											oleDbParameter.OleDbType = OleDbType.LongVarWChar;
											dbParameter.Value = SerializationManager.Serialize(value);
											break;
										case DbType.String:
											if (value.ToString().Length > 2000)
											{
												oleDbParameter.OleDbType = OleDbType.LongVarWChar;
											}
											break;
										case DbType.Time:
											oleDbParameter.OleDbType = OleDbType.LongVarWChar;
											dbParameter.Value = value.ToString();
											break;
										}
									}
									else
									{
										oleDbParameter.OleDbType = OleDbType.LongVarWChar;
										dbParameter.Value = value.ToString();
									}
									break;
								}
							}
						}
					}
				}
			}
			cmd.CommandText = cmd.CommandText.Replace("N'", "'");
			cmd.CommandText = cmd.CommandText.Replace("upper(", "ucase(").Replace("lower(", "lcase(").Replace("substring(", "mid(").Replace("getdate()", "date() + time()").Replace("datepart(year", "datepart('yyyy'").Replace("datepart(month", "datepart('m'").Replace("datepart(day", "datepart('d'");
			if (REGEX_ISNULL.IsMatch(cmd.CommandText))
			{
				Match match = REGEX_ISNULL.Match(cmd.CommandText);
				Group group = match.Groups[1];
				Group group2 = match.Groups[2];
				cmd.CommandText = REGEX_ISNULL.Replace(cmd.CommandText, " iif( isnull({0}),{1},{0} )".FormatWith(new object[]
				{
					group,
					group2
				}));
			}
		}
	}
}
